package com.toolbox.dal.repository.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.toolbox.bo.AccountBO;
import com.toolbox.dal.repository.InfraRoleDORepository;
import com.toolbox.dto.InfraRoleDTO;
import com.toolbox.dal.mapper.InfraRoleMapper;
import com.toolbox.dal.model.InfraRoleDO;
import com.toolbox.pages.Pager;
import com.toolbox.req.InfraRoleReq;
import com.toolbox.util.CopyBeanUtilExt;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.toolbox.pages.PageUtil.convert;
import static com.toolbox.pages.PageUtil.defaultObjWhenEmpty;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author Mango
 * @since 2023-12-01
 */
@SuppressWarnings("ALL")
@Slf4j
@Service
public class InfraRoleDORepositoryImpl extends ServiceImpl<InfraRoleMapper, InfraRoleDO> implements InfraRoleDORepository {

    @Autowired
    private InfraRoleMapper mapper;

    @Override
    public Pager<InfraRoleDTO> getRolePage(Integer pageIndex, Integer pageSize, String keywords) {
        QueryWrapper<InfraRoleDO> queryWrapper = new QueryWrapper<>();

        queryWrapper.lambda().like(!StrUtil.isBlank(keywords), InfraRoleDO::getName, keywords);

        queryWrapper.lambda().orderByAsc(InfraRoleDO::getId);

        Page<InfraRoleDO> page = mapper.selectPage(new Page<InfraRoleDO>(pageIndex, pageSize), queryWrapper);

        if (page.getRecords().isEmpty()) {
            return defaultObjWhenEmpty();
        }

        return convert(page.getTotal(), page.getCurrent(), page.getSize(), page.getRecords().stream().map(this::doToDto).collect(Collectors.toList()));
    }

    @Override
    public List<InfraRoleDTO> getRoleList() {
        List<InfraRoleDO> list = mapper.selectList(null);

        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        return list.stream().map(this::doToDto).sorted(Comparator.comparing(InfraRoleDTO::getId)).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Long createRole(InfraRoleReq req, AccountBO bo) {
        InfraRoleDO infraRoleDO = CopyBeanUtilExt.dtoToDo(req, InfraRoleDO.class);

        infraRoleDO.setCreatorId(bo.getUserId());
        infraRoleDO.setCreatorName(bo.getNickname());

        infraRoleDO.setModifierId(bo.getUserId());
        infraRoleDO.setModifierName(bo.getNickname());

        mapper.insert(infraRoleDO);

        return infraRoleDO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Long updateRoleById(InfraRoleReq req, AccountBO bo) {
        InfraRoleDO oldRoleBO = mapper.selectById(req.getId());

        oldRoleBO.setName(req.getName());
        oldRoleBO.setDescription(req.getDescription());

        oldRoleBO.setModifierId(bo.getUserId());
        oldRoleBO.setModifierName(bo.getNickname());

        mapper.updateById(oldRoleBO);

        return oldRoleBO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void removeById(Long id) {
        mapper.deleteById(id);
    }

    /**
     * DO 转换 DTO
     *
     * @param dos
     * @return
     */
    private InfraRoleDTO doToDto(InfraRoleDO dos) {
        InfraRoleDTO dto = new InfraRoleDTO();
        BeanUtils.copyProperties(dos, dto);
        return dto;
    }

}
